home *** CD-ROM | disk | FTP | other *** search
/ Delphi Programmer's Power Pack / Delphi Volume 1.iso / e_to_l / fbuilder / delphi / demos / dbfuncs.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-09-15  |  12.4 KB  |  472 lines

  1. {*                                *}
  2. {*  FormulaBuilder 1.0            *}
  3. {*  YGB Software, Inc.            *}
  4. {*  Copyright 1995 Clayton Collie *}
  5. {*  All Rights Reserved           *}
  6. Unit DBFuncs;
  7. Interface
  8. Uses Sysutils,DB,DBTables,FBDBCOMP;
  9.  
  10. {* This Demonstration unit implements the functions
  11.  
  12.    DBSUM( Expression <,Criteria > )
  13.    DBAVG( Expression <,Criteria > )
  14.    DBMAX( Expression <,Criteria > )
  15.    DBMIN( Expression <,Criteria > )
  16.    DBCOUNT(< Criteria >)
  17.  
  18.   These functions work only if called from a TDSExpression or descendant.
  19.   To use these functions, simply include this unit in the USES statement
  20.   of any unit in your project.
  21.  
  22.   These functions duplicate functionality existing within the BDE,
  23.   but they are useful in demonstrating useful techniques for using
  24.   FormulaBuilder.
  25.  
  26. *}
  27.  
  28.  
  29. IMPLEMENTATION
  30. uses  FBCALC;
  31.  
  32. Var fnIdDBSUM,fnIdDBAVG, fnIdDBMAX, fnIdDBMIN, fnidDBCOUNT : integer;
  33.  
  34.  
  35. Procedure PrepareDataset( dataset : TDataset; var bookmark : TBookmark );
  36. begin
  37.   {* Disable any components that reference the dataset.  Don't
  38.      want those updating while we traverse the table. *}
  39.    dataset.DisableControls;
  40.    BookMark := dataset.GetBookMark;
  41. end;
  42.  
  43.  
  44. Procedure RestoreDataset( dataset : TDataset; var bookmark : TBookmark );
  45. begin
  46.    With dataset do
  47.    begin
  48.      GotoBookmark(BookMark);
  49.      FreeBookmark(BookMark);
  50.      EnableControls;
  51.    end;
  52. end;
  53.  
  54.  
  55.  
  56.  
  57. {
  58. Common Routines for the DBXXX functions
  59. }
  60. CONST
  61.       INF      = 1.1E+4932;  {Extended}
  62.       NEGINF   = 3.4E-4932;  {Extended}
  63.  
  64.  
  65. Function DBGetParams(ExprData           : longint;
  66.                      var   DBDataset    : TDataset;
  67.                      const ExprString,
  68.                            FilterString : String;
  69.                      var   ExprIterator,
  70.                            ExprFilter   : TDSExpression) : Integer;
  71. var ntype : byte;
  72. begin
  73.   Result := EXPR_SUCCESS;
  74.   TRY
  75.      { NOTE! - this ONLY WORKS IF this proc IS CALLED FROM A
  76.        TCustomDSEXPRESSION or descendant !}
  77.      DBDataset := TDSExpression(ExprData).DataSet;
  78.    EXCEPT
  79.      Result := EXPR_INVALID_DATASET;  { Invalid_Expression }
  80.      exit;
  81.    END;
  82.    exprFilter := NIL;
  83.    exprIterator := TDSExpression.Create(NIL);
  84.    TRY
  85.      with ExprIterator do
  86.      begin
  87.        UseExceptions := False;
  88.        Dataset       := DBDataSet;
  89.        Formula       := ExprString;
  90.        Result        := Status;
  91.        if Result <> EXPR_SUCCESS then
  92.        begin
  93.          Free;
  94.          Exit;
  95.        end;
  96.        ntype := ReturnType;
  97.        if not (ntype in [vtINTEGER,vtFLOAT]) then
  98.        begin
  99.          result := EXPR_TYPE_MISMATCH;
  100.          free;
  101.          exit;
  102.        end;
  103.      end;
  104.      if FilterString = '' then exit;
  105.      exprFilter := TDSExpression.Create(NIL);
  106.      with exprFilter do
  107.      begin
  108.          UseExceptions := False;
  109.          Dataset       := DBDataset;
  110.          Formula       := FilterString;
  111.          Result        := Status;
  112.          if Result <> EXPR_SUCCESS then
  113.          begin
  114.            exprIterator.Free;
  115.            Free;
  116.            Exit;
  117.          end;
  118.          if not (ReturnType = vtBOOLEAN) then
  119.          begin
  120.            Result := EXPR_TYPE_MISMATCH;    { EXPR_INVALID_FILTER }
  121.            exprIterator.Free;
  122.            free;
  123.            exit;
  124.          end;
  125.        end; { With ExprFilter }
  126.    EXCEPT
  127.      ExprIterator.Free;
  128.      exprFilter.Free;
  129.    END;
  130. end;
  131.  
  132. {********}
  133.  
  134. { DBSum(Formula<,Criteria >) }
  135.  
  136. Procedure DBSUM( nParamcount    : byte;
  137.                 const params   : TActParamList;
  138.                 var ReturnVal  : TVALUEREC;
  139.                 var nErrCode   : Integer;
  140.                 ExprData       : longint); export;
  141. var
  142.   fDBSUMResult : double;
  143.   exprCriteria : TDSExpression;
  144.   exprDBSUM    : TDSExpression;
  145.   tblDBSUM     : TDataset;
  146.   BookMark     : TBookMark;
  147.   ntype        : byte;
  148.   sfilter      : string;
  149.  
  150. begin
  151.   if nParamCount = 2 then
  152.      sFilter := params[1].vpString^
  153.    else
  154.      sFilter := '';
  155.   nErrCode := DBGetParams(ExprData,tblDBSUM,params[0].vpString^,sFilter,
  156.                           ExprDBSUM,exprCriteria);
  157.  
  158.   if nErrCode <> EXPR_SUCCESS then exit;
  159.   TRY
  160.     ntype        := ExprDBSum.ReturnType;
  161.     fDBSUMResult := 0;
  162.     PrepareDataset(tblDBSUM,BookMark);
  163.     TRY
  164.        tblDBSUM.First;
  165.        while not tblDBSUM.EOF do
  166.        begin
  167.           if (nParamCount = 1) or exprCriteria.AsBoolean then
  168.           Case ntype of
  169.               vtINTEGER : fDBSUMResult := fDBSUMResult + exprDBSUM.AsInteger;
  170.               vtFLOAT   : fDBSUMResult := fDBSUMResult + exprDBSUM.AsFloat;
  171.           end;
  172.           tblDBSUM.Next;
  173.         end;
  174.         ReturnVal.vFloat := fDBSUMResult;
  175.     FINALLY
  176.        RestoreDataset(tblDBSUM,BookMark);
  177.     END;
  178.     nErrcode := EXPR_SUCCESS;  { not really necessary, since this is its value on entry }
  179.    FINALLY
  180.      ExprDBSUM.Free;
  181.      exprCriteria.Free;
  182.    END;
  183. end;
  184.  
  185.  
  186.  
  187. { DBAVG(Formula<,Criteria >) }
  188.  
  189. Procedure DBAVG( nParamcount    : byte;
  190.                 const params   : TActParamList;
  191.                 var ReturnVal  : TVALUEREC;
  192.                 var nErrCode   : Integer;
  193.                 ExprData       : longint); export;
  194. var
  195.   fDBAVGResult : double;
  196.   exprCriteria : TDSExpression;
  197.   exprDBAVG    : TDSExpression;
  198.   tblDBAVG     : TDataset;
  199.   lCount       : longint;
  200.   BookMark     : TBookMark;
  201.   ntype        : byte;
  202.   sfilter      : string;
  203.  
  204. begin
  205.   if nParamCount = 2 then
  206.      sFilter := params[1].vpString^
  207.    else
  208.      sFilter := '';
  209.   nErrCode := DBGetParams(ExprData,tblDBAVG,params[0].vpString^,sFilter,
  210.                           ExprDBAVG,exprCriteria);
  211.  
  212.   if nErrCode <> EXPR_SUCCESS then exit;
  213.   TRY
  214.     ntype := ExprDBAVG.ReturnType;
  215.     fDBAVGResult := 0;
  216.     PrepareDataset(tblDBAVG,BookMark);
  217.     lCount := 0;
  218.     TRY
  219.        tblDBAVG.First;
  220.        while not tblDBAVG.EOF do
  221.        begin
  222.          if (nParamCount = 1) or exprCriteria.AsBoolean then
  223.          begin
  224.            Case ntype of
  225.               vtINTEGER : fDBAVGResult := fDBAVGResult + exprDBAVG.AsInteger;
  226.               vtFLOAT   : fDBAVGResult := fDBAVGResult + exprDBAVG.AsFloat;
  227.            end;
  228.            inc(lCount);
  229.           end;
  230.           tblDBAVG.Next;
  231.         end;
  232.         if lCount = 0 then
  233.            fDBAVGResult := 0
  234.          else
  235.            fDBAVGResult := (fDBAvgResult / lCount);
  236.          ReturnVal.vFloat := fDBAVGResult;
  237.      FINALLY
  238.        RestoreDataset(tblDBAVG,BookMark);
  239.      END;
  240.      nErrcode := EXPR_SUCCESS;  { not really necessary, since this is its value on entry }
  241.    FINALLY
  242.      ExprDBAVG.Free;
  243.      exprCriteria.Free;
  244.    END;
  245. end;
  246.  
  247.  
  248.  
  249. { DBCOUNT(< Criteria >) }
  250.  
  251. Procedure DBCOUNT( nParamcount    : byte;
  252.                    const params   : TActParamList;
  253.                    var ReturnVal  : TVALUEREC;
  254.                    var nErrCode   : Integer;
  255.                    ExprData       : longint); export;
  256. var
  257.   exprFilter   : TDSExpression;
  258.   tblDBCOUNT   : TDataset;
  259.   lCount       : longint;
  260.   BookMark     : TBookMark;
  261.   ntype        : byte;
  262.  
  263. begin
  264.   TRY
  265.      tblDBCOUNT := TDSExpression(ExprData).DataSet;
  266.    EXCEPT
  267.      nErrCode := EXPR_INVALID_DATASET;  { Invalid_Expression }
  268.      exit;
  269.    END;
  270.   if (nParamcount = 0) or (params[0].vpString^ = '') then
  271.   begin
  272.     ReturnVal.vInteger := tblDBCOUNT.RecordCount;
  273.     exit;
  274.   end;
  275.   exprFilter := TDSExpression.Create(NIL);
  276.   with exprFilter do
  277.   begin
  278.     UseExceptions := False;
  279.     Dataset       := tblDBCOUNT;
  280.     Formula       := params[0].vpString^;
  281.     nErrCode      := Status;
  282.     if nErrCode <> EXPR_SUCCESS then
  283.     begin
  284.       Free;
  285.       Exit;
  286.     end;
  287.     if not (ReturnType = vtBOOLEAN) then
  288.     begin
  289.       nErrCode := EXPR_TYPE_MISMATCH;    { EXPR_INVALID_FILTER }
  290.       free;
  291.       exit;
  292.     end;
  293.   end; {with }
  294.   TRY
  295.     PrepareDataset(tblDBCOUNT,BookMark);
  296.     lCount := 0;
  297.     TRY
  298.       tblDBCOUNT.First;
  299.       while not tblDBCOUNT.EOF do
  300.       begin
  301.         inc(lcount,ord(exprFilter.AsBoolean));
  302.         if exprFilter.Status <> EXPR_SUCCESS then
  303.         begin
  304.           nErrCode := exprFilter.Status;
  305.           RestoreDataset(tblDBCOUNT,BookMark);
  306.           exit;
  307.          end;
  308.          tblDBCOUNT.Next;
  309.        end;
  310.        ReturnVal.vInteger := lCount;
  311.      FINALLY
  312.        RestoreDataset(tblDBCOUNT,BookMark);
  313.      END;
  314.      nErrcode := EXPR_SUCCESS;  { not really necessary, since this is its value on entry }
  315.     FINALLY
  316.       exprFilter.Free;
  317.     END;
  318. end; { DBCOunt }
  319.  
  320.  
  321.  
  322. { DBMIN(Formula<,Criteria >) }
  323.  
  324. Procedure DBMIN( nParamcount    : byte;
  325.                  const params   : TActParamList;
  326.                  var ReturnVal  : TVALUEREC;
  327.                  var nErrCode   : Integer;
  328.                  ExprData       : longint); export;
  329. var
  330.   fDBMINResult : extended;
  331.   fTemp        : extended;
  332.   exprCriteria : TDSExpression;
  333.   exprDBMIN    : TDSExpression;
  334.   tblDBMIN     : TDataset;
  335.   BookMark     : TBookMark;
  336.   ntype        : byte;
  337.   sfilter      : string;
  338.  
  339. begin
  340.   if nParamCount = 2 then
  341.      sFilter := params[2].vpString^
  342.    else
  343.      sFilter := '';
  344.   nErrCode := DBGetParams(ExprData,tblDBMIN,params[0].vpString^,sFilter,
  345.                           ExprDBMIN,exprCriteria);
  346.  
  347.   if nErrCode <> EXPR_SUCCESS then exit;
  348.  
  349.   ntype        := exprDBMIN.ReturnType;
  350.   fDBMINResult := INF;
  351.   TRY
  352.     PrepareDataset(tblDBMIN,BookMark);
  353.     TRY
  354.        tblDBMIN.First;
  355.        while not tblDBMIN.EOF do
  356.        begin
  357.          if (nParamCount = 1) or exprCriteria.AsBoolean then
  358.          begin
  359.             Case ntype of
  360.                 vtINTEGER : fTemp := exprDBMIN.AsInteger;
  361.                 vtFLOAT   : fTemp := exprDBMIN.AsFloat;
  362.             end;
  363.             if fTemp < fDBMINResult then
  364.                fDBMINResult := fTemp;
  365.           end;
  366.           tblDBMIN.Next;
  367.         end;
  368.         ReturnVal.vFloat := fDBMINResult;
  369.       FINALLY
  370.         RestoreDataset(tblDBMIN,BookMark);
  371.       END;
  372.       nErrcode := EXPR_SUCCESS;  { not really necessary, since this is its value on entry }
  373.     FINALLY
  374.       ExprDBMIN.Free;
  375.       exprCriteria.Free;
  376.     END;
  377. end;
  378.  
  379.  
  380.  
  381. { DBMAX(Formula<,Criteria >) }
  382.  
  383. Procedure DBMAX( nParamcount    : byte;
  384.                  const params   : TActParamList;
  385.                  var ReturnVal  : TVALUEREC;
  386.                  var nErrCode   : Integer;
  387.                  ExprData       : longint); export;
  388. var
  389.   fDBMAXResult : extended;
  390.   fTemp        : double;
  391.   exprCriteria : TDSExpression;
  392.   exprDBMAX    : TDSExpression;
  393.   tblDBMAX     : TDataset;
  394.   BookMark     : TBookMark;
  395.   ntype        : byte;
  396.   sfilter      : string;
  397.  
  398. begin
  399.   if nParamCount = 2 then
  400.      sFilter := params[2].vpString^
  401.    else
  402.      sFilter := '';
  403.   nErrCode := DBGetParams(ExprData,tblDBMAX,params[0].vpString^,sFilter,
  404.                           ExprDBMAX,exprCriteria);
  405.  
  406.   if nErrCode <> EXPR_SUCCESS then exit;
  407.  
  408.   ntype := ExprDBMAX.ReturnType;
  409.   fDBMAXResult := 0;
  410.   TRY
  411.      PrepareDataset(tblDBMAX,BookMark);
  412.      TRY
  413.        tblDBMAX.First;
  414.        while not tblDBMAX.EOF do
  415.        begin
  416.          if (nParamCount = 1) or exprCriteria.AsBoolean then
  417.          begin
  418.             Case ntype of
  419.                  vtINTEGER : fTemp := exprDBMAX.AsInteger;
  420.                  vtFLOAT   : fTemp := exprDBMAX.AsFloat;
  421.              end;
  422.              if fTemp > fDBMAXResult then
  423.                 fDBMAXResult := fTemp;
  424.           end;
  425.           tblDBMAX.Next;
  426.         end;
  427.         ReturnVal.vFloat := fDBMAXResult;
  428.       FINALLY
  429.         RestoreDataset(tblDBMAX,BookMark);
  430.       END;
  431.       nErrcode := EXPR_SUCCESS;  { not really necessary, since this is its value on entry }
  432.    FINALLY
  433.      ExprDBMAX.Free;
  434.      exprCriteria.Free;
  435.    END;
  436. end;
  437.  
  438.  
  439.  
  440.  
  441. Procedure RegisterFunctions;
  442. begin
  443.   InitFbuilder;
  444.   If not FBLoaded then exit;
  445.   fnIdDBSUM   := FBRegisterFunction('DBSUM',vtFLOAT,'ss',1,DBSUM);
  446.   fnIdDBMIN   := FBRegisterFunction('DBMIN',vtFLOAT,'ss',1,DBMIN);
  447.   fnIdDBMAX   := FBRegisterFunction('DBMAX',vtFLOAT,'ss',1,DBMAX);
  448.   fnIdDBAVG   := FBRegisterFunction('DBAVG',vtFLOAT,'ss',1,DBAVG);
  449.   fnIdDBCOUNT := FBRegisterFunction('DBSUM',vtINTEGER,'s',0,DBCOUNT);
  450. end;
  451.  
  452.  
  453. Procedure UnRegisterFunctions; far;
  454. begin
  455.   if not FBLoaded then exit;
  456.   FBUnregisterFunction(fnIdDBSUM);
  457.   FBUnregisterFunction(fnIdDBMAX);
  458.   FBUnregisterFunction(fnIdDBMIN);
  459.   FBUnregisterFunction(fnIdDBAVG);
  460.   FBUnregisterFunction(fnIdDBCOUNT);
  461.   FreeFBuilder;
  462. end;
  463.  
  464.  
  465.  
  466.  
  467. INITIALIZATION
  468.   RegisterFunctions;
  469.   AddExitProc(UnRegisterFunctions);
  470. END.
  471.  
  472.